/**
 * 异步组件工厂
 * 
 * 1.路由配置后，当组件被使用时再请求相应模板文件，生成组件构造对象
 * 2.默认以组件名称作为请求的文件名称
 * 3.请求路径默认为 htmls/[moduleName]/[componentName].html
 * 
 * @param {Object} path "模块名/组件名"
 */
(function() {
	'use strict';

	function asyncComponent(path) {
		if(!path) console.error("component path can not be empty.");
		
		var pathArray = path.split("/");
		var moduleName =  pathArray[0], componentName = pathArray[1];

		var rootPath = "html/" + moduleName + "/" + componentName + ".html";

		if(!window[moduleName]) window[moduleName] = {};

		function buildTemplate(page, scripts) {
			var elem,
				template = document.createElement("div"),
				tmp = document.createElement("div");
			tmp.innerHTML = page;
			var i = 0,
				j;
			while((elem = tmp.childNodes[i++])) {
				switch(elem.nodeName) {
					case "STYLE":
					case "LINK":
						document.head.appendChild(elem);
						break;
					case "SCRIPT":
						scripts.push(elem);
						break;
					case "TEMPLATE":
						template.innerHTML = elem.innerHTML;
				}

			}
			return template;
		}

		function resolveComponentConstructor(resolve, template) {
			if(window[moduleName] && window[moduleName][componentName]) {
				var componentConstructor = window[moduleName][componentName]();
				if(!componentConstructor.template) componentConstructor.template = template;
				resolve(componentConstructor);
			}
		}

		// 这个是vue-router里面的方法
		return function(resolve, reject) {
			Vue.http.get(rootPath).then(function(response) {
				var elem, i = 0,
					scripts = [],
					template = buildTemplate(response.data, scripts);
				while(elem = scripts[i++]) {
					var script = document.createElement("script");
					if(!elem.src) {
						script.text = elem.textContent;
						document.head.appendChild(script).parentNode.removeChild(script);
						resolveComponentConstructor(resolve, template);
					} else {
						script.src = elem.src;
						document.head.appendChild(script).parentNode.removeChild(script);
						script.onload = script.onreadystatechange = function() {
							resolveComponentConstructor(resolve, template);
						}
					}
				}
			});
		}
	}

	function plugin(Vue) {
		if(plugin.installed) {
			return;
		}
		Vue.asyncComponent = asyncComponent;
	}
	if(typeof window !== 'undefined' && window.Vue) {
		window.Vue.use(plugin);
	}
}());